package cn.sytton.taffe.framework.captcha;

import cn.hutool.core.img.ImgUtil;
import cn.sytton.taffe.framework.factory.RedisUtil;
import com.google.code.kaptcha.Producer;
import cn.sytton.taffe.framework.constants.RedisKey;
import cn.sytton.taffe.framework.properties.auth.AuthProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.awt.image.BufferedImage;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 图形验证码控制工厂
 *
 * @author skyrock
 */
@Component
public class CaptchaFactory {

    @Resource(name = "captchaProducerChar")
    private Producer captchaProducerChar;

    @Resource(name = "captchaProducerMath")
    private Producer captchaProducerMath;

    @Resource
    private AuthProperties authProperties;

    @Resource
    private RedisUtil redisUtil;

    /**
     * 生成图片验证码对象
     * @return 片验证码对象
     */
    public Captcha generateCode() {

        String capStr, code;
        BufferedImage image;

        // 生成验证码, 默认数字计算类型
        String type = authProperties.getCaptcha().getType().name();
        if (!StringUtils.hasText(type) || CaptchaType.MATH.name().equalsIgnoreCase(type)) {
            String capText = captchaProducerMath.createText();
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            code = capText.substring(capText.lastIndexOf("@") + 1);
            image = captchaProducerMath.createImage(capStr);
        } else if (CaptchaType.CHAR.name().equalsIgnoreCase(type)){
            capStr = code = captchaProducerChar.createText();
            image = captchaProducerChar.createImage(capStr);
        } else {
            return new Captcha();
        }

        assert image != null;
        Captcha captcha = new Captcha(UUID.randomUUID().toString(), ImgUtil.toBase64(image, "jpg"), code);

        redisUtil.setObject(getRedisKey(captcha.getCaptchaId()), captcha.getCode(), authProperties.getCaptcha().getExpireTime(), TimeUnit.MINUTES);

        return captcha;
    }

    /**
     * 验证图片验证码
     * @return true/false
     */
    public Boolean verifyCode(String id, String code) {
        if (!authProperties.getCaptcha().isEnabled()) {
            return true;
        } else {
            String originCode = redisUtil.getObject(getRedisKey(id), String.class);
            if (StringUtils.hasText(originCode)) {
                return originCode.equalsIgnoreCase(code);
            } else {
                return false;
            }
        }
    }

    private String getRedisKey(String id) {
        return RedisKey.CAPTCHA_ID_KEY+id;
    }
}
